<template>
  <div class="app-container">
    <!-- 项目信息 -->
    <el-card shadow="hover" header="项目信息" v-loading="planLoading">
      <div class="disf dirc h pr30">
        <el-form label-width="100px">
          <el-form-item label="合同名称">
            {{ contractBuild?.contractName }}
          </el-form-item>
          <el-form-item label="负责人">
            {{ contractBuild?.majorUsername }}
          </el-form-item>
          <el-form-item label="参与人">
            {{ contractBuild?.userIds.map((u) => u.username).join("、") }}
          </el-form-item>
          <!-- <el-form-item label="工艺人员">
            <el-button type="primary" size="small" class="mr15" @click="handleGyDispatch">
              分派人员
            </el-button>
            {{ gyUsers.map((u) => `${u.username}（${u.name}）`).join("、") }}
          <el-form-item label="工艺人员">
            <span>请在任务上分派人员</span>
          </el-form-item>
          </el-form-item> -->
        </el-form>
      </div>
    </el-card>
    <!-- 项目进度 -->
    <el-card class="mt10" shadow="hover" header="项目进度">
      <el-scrollbar always class="flex1 ml30" v-if="activityId">
        <div class="flow-node-wrap" v-loading="flowLoading">
          <!-- 遍历：节点列表 -->
          <template v-for="(node, idx) in nodeList" :key="node.id">
            <div class="flow-node">
              <!-- 节点名称 -->
              <div class="node-name">
                <div class="node-index ml25">{{ idx + 1 }}</div>
                <div class="disf dirc flex1 w0 plr15">
                  <b>{{ node.name }}</b>
                  <span class="node-remark" :title="node.remark">
                    {{ node.remark || "暂无描述" }}
                  </span>
                </div>
                <el-tag type="primary" effect="plain" class="node-tag mr15">
                  {{ FLOW_NODE_TYPE_LABEL[node.nodeType] }}
                  <el-tooltip v-if="node.nodeType == FlowNodeType.AUDITOR_NODE" :content="getAuditBackName(node)"
                    placement="top">
                    <el-icon style="cursor: pointer">
                      <QuestionFilled />
                    </el-icon>
                  </el-tooltip>
                </el-tag>
              </div>
              <!-- 节点任务列表 -->
              <ol class="node-tasks">
                <li class="task-line" v-for="task in node.tasks">
                  <div class="task-title">
                    <b>{{ task.name }}</b>
                    <span class="role-icon">
                      <el-icon class="mr5">
                        <User />
                      </el-icon>
                      {{ FLOW_ACT_ROLE_LABEL[task.activityRole] }}
                    </span>
                  </div>
                  <div class="task-remark" :title="task.remark">
                    <span>{{ task.remark }}</span>
                  </div>
                  <div class="task-remark disf alc">
                    <el-icon class="mr5">
                      <Postcard />
                    </el-icon>
                    {{ FLOW_CANDIDAT_TYPE_LABEL[task.candidateType] }}【{{ task.candidateName }}】
                  </div>
                  <div class="task-remark disf alc" :title="getGyUsers(task.id)">
                    <el-icon class="mr5">
                      <Brush />
                    </el-icon>
                    <div class="txt-ellipsis">
                      {{ getGyUsers(task.id) || "暂无" }}
                    </div>
                  </div>

                  <div class="task-remark disf alc juend">
                    <el-button size="small" link icon="warning" type="primary" @click="handleDtlTask(task.id)">
                      详情
                    </el-button>
                    <el-button type="primary" size="small" link icon="User" @click="handleGyDispatch(task)">
                      分派工艺人员
                    </el-button>
                  </div>
                </li>
              </ol>
            </div>
          </template>
        </div>
      </el-scrollbar>
      <el-empty v-else description="暂无数据，请联系管理员"></el-empty>
    </el-card>
    <!-- 项目台账 -->
    <el-card class="mt10" shadow="hover">
      <template #header>
        <span>项目台账</span>
        <el-button :disabled="!!(ledgerList.length && ledgerList[0].status == 0)" :title="ledgerList.length && ledgerList[0].status == 0
      ? '暂时无法修改，有待审核的台账修改申请'
      : '修改台账'
      " type="primary" size="small" class="ml10" @click="handleEditLedger">
          {{ modifyStatus ? '保存修改' : '修改台账' }}
        </el-button>
        <el-button type="primary" v-if="modifyStatus" size="small" class="ml10" @click="cancelEditLedger">
          取消修改
        </el-button>
        <el-button type="primary" v-if="modifyStatus" size="small" class="ml10" @click="showMaterialWindow">
          新增材料
        </el-button>
      </template>
      <el-table ref="dataTableRef" v-loading="loading" :data="contractItems" height="calc(100% - 40px)"
        highlight-current-row v-if="formData">
        <el-table-column label="材料名称" prop="name" />
        <el-table-column label="材料类型" width="120">
          <template #default="scope">
            {{ SaleMealTypeLabel[scope.row.itemType] }}
          </template>
        </el-table-column>
        <el-table-column label="规格" prop="spec" />
        <el-table-column label="单位" prop="unit" />
        <!-- <el-table-column label="数量" align="center" prop="quantity" /> -->
        <el-table-column label="数量" align="center" prop="quantity" width="100">
          <template #default="scope">
            <el-input-number :disabled="!modifyStatus" v-model="scope.row.quantity" size="small" style="width: 100%"
              :min="1" controls-position="right" />
          </template>
        </el-table-column>
        <!-- <el-table-column label="单价" align="right" prop="price">
          <template #default="scope">
            {{ `￥${scope.row.price}` }}
          </template>
        </el-table-column> -->
        <el-table-column label="单价" align="center" prop="price" width="180">
          <template #default="scope">
            <el-input-number :disabled="!modifyStatus" v-model="scope.row.price" size="small" :precision="2" :step="1"
              :min="0.01" style="width: 100%">
              <template #prefix>
                <span>￥</span>
              </template>
            </el-input-number>
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" width="100" align="center">
          <template #default="scope">
            <el-button v-if="modifyStatus" size="small" type="danger" link @click="handleDeleteItem(scope.row)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 台账记录 -->
    <el-card class="mt10" shadow="hover" header="台账记录">
      <el-timeline>
        <el-timeline-item v-for="(ledger, idx) in ledgerList" :key="ledger.id" :timestamp="ledger.createTime"
          placement="top">
          <p class="disf alc">
            {{ ledger.username }}已提交项目台账修改申请，原因：{{ ledger.title }}。审批状态：{{
      ContractLedger_Status_Label[ledger.status]
    }}{{ ledger.remark ? `，审批建议：${ledger.remark}` : "" }}。
            <el-button type="primary" link @click="showLedger(idx)">查看详情</el-button>
          </p>
        </el-timeline-item>
      </el-timeline>
    </el-card>

    <!-- 弹窗：分派人员 -->
    <el-dialog v-model="dialogGyDispatch.visible" :title="dialogGyDispatch.title" width="800px"
      @close="closeGyDispatch">
      <el-table class="w" v-loading="dialogGyDispatch.loading" :data="dialogGyDispatch.data">
        <el-table-column label="工艺名称" width="300">
          <template #default="scope">
            <el-input v-model="scope.row.name" autocomplete="off" placeholder="请输入工艺名称" />
          </template>
        </el-table-column>
        <el-table-column label="人工定额" width="150">
          <template #default="scope">
            <el-select v-model="scope.row.normId" placeholder="请选择" filterable>
              <el-option v-for="c in normOpts" :key="c.value" :label="c.label" :value="c.value" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="人员" width="150">
          <template #default="scope">
            <el-select v-model="scope.row.userId" placeholder="请选择" filterable>
              <el-option v-for="c in userOpts" :key="c.value" :label="c.label" :value="c.value" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template #default="scope">
            <el-button size="small" type="primary" link @click="handleAddGy(scope.$index)">
              添加
            </el-button>
            <el-button size="small" type="danger" link @click="handleDeleteGy(scope.row)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleSubmitGyDispatch">确 定</el-button>
          <el-button @click="closeGyDispatch">取 消</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 弹窗：查询节点任务 -->
    <TaskDetail :id="dialogTaskDtl.id" :visible="dialogTaskDtl.visible" @dialogClose="closeDtlTask"></TaskDetail>
    <!-- 弹窗：设计台账修改 -->
    <el-dialog v-model="dialogEditLedger.visible" :title="dialogEditLedger.title" width="1100px"
      @close="closeEditLedger">
      <EditLedger :data="dialogEditLedger.data" :id="id" ref="editLedgerRef" />
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleSubmitLedger">确 定</el-button>
          <el-button @click="closeEditLedger">取 消</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 弹窗：设计台账记录 -->
    <el-dialog v-model="dialogLedger.visible" :title="dialogLedger.title" width="1100px" @close="closeLedger">
      <Ledger :data="dialogLedger.data" :old-data="dialogLedger.oldData" ref="ledgerRef" />
    </el-dialog>

    <!-- 弹窗：选材料-->
    <el-dialog v-model="chooseMaterialVisible" title="选择材料" width="800px" @close="closeMaterialWindow">
      <MaterialSelector ref="materialRef" :withNorm="true" operation="add" @addItem="addMaterial" />
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="chooseMaterialDone">确 定</el-button>
          <el-button @click="closeMaterialWindow">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import TaskDetail from "@/views/flow/buildPlan/components/taskDetail.vue";
import EditLedger from "./editLedger.vue";
import Ledger from "./ledgerRecord.vue";
import { FLOW_AUDIT_TYPE_LABEL, FLOW_NODE_TYPE_LABEL, FlowNodeType } from "@/api/flow/flowNode.api";
import { FLOW_ACT_ROLE_LABEL, FLOW_CANDIDAT_TYPE_LABEL } from "@/api/flow/flowNodeTask.api";
import BuildAPI, { BuildApproveForm, BuildDetailVO } from "@/api/flow/build.api";
import { decryptDES } from "@/utils/des";
import ActivityAPI from "@/api/flow/activity.api";
import { ActivityNodeVO } from "@/api/flow/activityNode.api";
import { SaleMealTypeLabel } from "@/api/business/material/sealMeal.api";
import { ContractItem } from "@/api/flow/contract.api";
import ContractLedgerAPI, {
  ContractLedger_Status_Label,
  ContractLedgerRecord,
  ContractLedgerRecordItem,
  ContractLedgerForm
} from "@/api/flow/contractLedger.api";
import TaskGyDispatchAPI, { TaskGyDispatchItem } from "@/api/flow/taskGyDispatch.api";
import UserAPI from "@/api/system/user.api";
import NormApi from "@/api/business/material/norm.api";
import { cloneDeep } from "lodash-es";
import { ActivityNodeTaskVO } from "@/api/flow/activityNodeTask.api";
import { toMapList } from "@/utils";
import { MaterialPageVO } from "@/api/business/material/material.api";
import MaterialSelector from "@/views/business/material/material/MaterialSelector.vue";

const route = useRoute();

const id = ref(""); // 合同id
const contractBuild = ref<BuildDetailVO>(); // 合同施工详情
const activityId = ref(""); //流程实例id
const activityInfo = ref(); //流程实例对象
const nodeList = ref<ActivityNodeVO[]>([]); //节点列表
const contractItems = ref<ContractItem[]>([]); //当前材料列表
const originalItems = ref<ContractItem[]>([]); //原始材料列表
const ledgerList = ref<ContractLedgerRecord[]>([]); //台账修改记录
const gyUsers = ref<any[]>([]); //工艺人员
const userOpts = ref<OptionType[]>([]); //候选者备选
const normOpts = ref<OptionType[]>([]); //人工定额备选
const editLedgerRef = ref();
const dispatchMap = ref<{ [key: string]: TaskGyDispatchItem[] }>({});
const modifyStatus = ref(false);
// 审批表单
const formData = reactive<BuildApproveForm>({
  contractId: "",
  pass: false,
  remark: "",
});

const planLoading = ref(false);
const flowLoading = ref(false);
const loading = ref(false);

const chooseMaterialVisible = ref(false);
const materialRef = ref();

watch(
  () => route.query.key,
  async (val) => {
    // 提取转换密文对象
    const str = decryptDES(val as string);
    const busiInfo = JSON.parse(str) || {}; //业务信息
    id.value = busiInfo.id;
    formData.contractId = id.value;
    // 获取实例id和详情
    await loadBase();
    await loadContractLedger();
    loadGyUsers();
    loadGyUsersOpt();
    loadGyNormOpt();
  },
  {
    immediate: true,
  }
);

// 加载基础信息
async function loadBase() {
  planLoading.value = true;
  try {
    contractBuild.value = await BuildAPI.loadDetail(id.value);
    activityId.value = contractBuild.value.activityId;
    activityId.value && loadFlowDetail();
  } catch (error) {
    console.log(error);
  }
  planLoading.value = false;
}

// 加载工艺分派人员
async function loadGyUsers() {
  const items = await TaskGyDispatchAPI.loadByContractId(id.value);
  dispatchMap.value = toMapList(items, "taskId");
}

// 加载节点列表
const loadFlowDetail = () => {
  if (!activityId.value) {
    nodeList.value = [];
    return;
  }
  flowLoading.value = true;
  // 加载流程
  ActivityAPI.load(activityId.value)
    .then((data) => {
      activityInfo.value = data;
      nodeList.value = data.activityNodes;
    })
    .finally(() => {
      flowLoading.value = false;
    });
};

// 加载台账
const loadContractLedger = async () => {
  await ContractLedgerAPI.load(id.value).then((data) => {
    contractItems.value = data.newItems || data.originalItems;
    originalItems.value = data.originalItems;
    ledgerList.value = data.records;
  });
};

// 加载备选人
async function loadGyUsersOpt() {
  const res = await UserAPI.getOptions();
  userOpts.value = res.map((r) => ({ label: r.realName, value: r.id }));
}
// 加载人工定额
async function loadGyNormOpt() {
  const res = await NormApi.loadRengong();
  normOpts.value = res.map((r) => ({ label: r.name!, value: r.id! }));
}

// 获取审核回退的节点
function getAuditBackName(node: ActivityNodeVO) {
  const backNode = nodeList.value.find((item) => item.id == node.backNodeId);
  return `审核方式：${FLOW_AUDIT_TYPE_LABEL[node.auditorType!]}，审核不通过回退至：${backNode?.name}`;
}

// 获取任务的工艺人员
function getGyUsers(taskId: string) {
  return dispatchMap.value[taskId]?.map((u) => `${u.normName}(${u.username})`).join("、");
}

/**
 * 弹窗:任务详情
 */
const dialogTaskDtl = reactive<{
  visible: boolean;
  id?: string;
}>({
  visible: false,
});
function handleDtlTask(id?: string) {
  dialogTaskDtl.visible = true;
  dialogTaskDtl.id = id;
}
function closeDtlTask() {
  dialogTaskDtl.visible = false;
}

/**
 * 工艺人员分派弹窗
 */
const dialogGyDispatch = reactive<{
  visible: boolean;
  title: string;
  loading: boolean;
  taskId: string;
  taskName: string;
  data: TaskGyDispatchItem[];
}>({
  visible: false,
  title: "工艺分派",
  loading: false,
  taskId: "0",
  taskName: "",
  data: [],
});
function handleGyDispatch(task: ActivityNodeTaskVO) {
  dialogGyDispatch.visible = true;
  dialogGyDispatch.taskId = task.id!;
  dialogGyDispatch.taskName = task.name;
  dialogGyDispatch.data = dispatchMap.value[task.id] || [];
  // dialogGyDispatch.data = cloneDeep(gyUsers.value);
  if (dialogGyDispatch.data.length == 0) {
    handleAddGy();
  }
}
function closeGyDispatch() {
  dialogGyDispatch.visible = false;
}
// 添加工艺人员
function handleAddGy(idx: number = 0) {
  dialogGyDispatch.data.splice(idx + 1, 0, {
    userId: "",
    name: "",
  });
}
// 删除工艺人员
function handleDeleteGy(item: TaskGyDispatchItem) {
  dialogGyDispatch.data.splice(dialogGyDispatch.data.indexOf(item), 1);
}
// 提交工艺人员
function handleSubmitGyDispatch() {
  const emptyUser = dialogGyDispatch.data.find((item) => !item.userId || !item.name);
  if (emptyUser) {
    ElMessage.warning("请输入工艺名称并选择人员");
    return;
  }
  TaskGyDispatchAPI.dispatch({
    contractId: id.value,
    taskId: dialogGyDispatch.taskId,
    taskName: dialogGyDispatch.taskName,
    taskGyDispatches: dialogGyDispatch.data,
  })
    .then((data) => {
      ElMessage.success("分派工艺人员成功");
      loadGyUsers();
      closeGyDispatch();
    })
    .catch((error) => {
      console.error(error.message);
    });
}

/**
 * 弹窗：设计修改
 */
const dialogEditLedger = reactive<{
  visible: boolean;
  title: string;
  loading: boolean;
  data: ContractItem[];
}>({
  visible: false,
  title: "设计台账修改",
  loading: false,
  data: [],
});
async function handleEditLedger() {
  // dialogEditLedger.visible = true;
  // dialogEditLedger.data = cloneDeep(contractItems.value);
  if (!modifyStatus.value) {
    modifyStatus.value = true;
  } else {
    modifyStatus.value = false;
    // 处理数据
    try {
      let formData: ContractLedgerForm = {
        contractId: id.value,
        title: '',
        items: contractItems.value,
      }
      await ContractLedgerAPI.reviewContract(formData);
      ElMessage.success("提交台账修改成功");
    } catch (error) {
      console.error("保存失败", error);
    }
  }
}

function cancelEditLedger() {
  modifyStatus.value = false;
}
function closeEditLedger() {
  dialogEditLedger.visible = false;
}
async function handleSubmitLedger() {
  await editLedgerRef.value.submit();
  ElMessage.success("提交台账修改成功");
  closeEditLedger();
  loadContractLedger();
}

/**
 * 弹窗：台账记录
 */
const dialogLedger = reactive<{
  visible: boolean;
  title: string;
  data?: ContractLedgerRecord;
  oldData?: ContractLedgerRecordItem[];
}>({
  visible: false,
  title: "台账记录详情",
});
function showLedger(idx: number) {
  dialogLedger.data = ledgerList.value[idx];
  // dialogLedger.oldData = idx == 0 ? originalItems.value : ledgerList.value[idx - 1].items;
  dialogLedger.visible = true;
}
function closeLedger() {
  dialogLedger.visible = false;
}

/**以下是选择材料弹框 */

function showMaterialWindow() {
  chooseMaterialVisible.value = true;
  nextTick(() => {
    materialRef.value.handleQuery();
  });
}

function chooseMaterialDone() {
  chooseMaterialVisible.value = false;
}

function closeMaterialWindow() {
  chooseMaterialVisible.value = false;
}

/**
 * 添加材料
 */
async function addMaterial(item: MaterialPageVO) {
  const oMeal = contractItems.value.find((m) => m.resourceId === item.id);
  if (oMeal) {
    oMeal.quantity++;
  } else {
    contractItems.value.push({
      resourceId: item.id,
      quantity: 1,
      name: item.name,
      price: item.price,
      unit: item.unit,
      itemType: item.type,
      remark: "",
      spec: item.spec,
    });
  }
}

// 删除材料
function handleDeleteItem(item: ContractItem) {
  contractItems.value = contractItems.value.filter((i) => i.id !== item.id);
}
</script>

<style lang="scss" scoped>
:deep(.el-card__body) {
  height: calc(100% - 70px);
}

.temp-item {
  border: 1px solid #eee;
  border-radius: 5px;
  padding: 10px 14px;
  margin-bottom: 10px;
  cursor: pointer;
  transition: all 0.3s ease-in-out;

  p {
    padding-bottom: 3px;
  }

  span {
    font-size: 0.75em;
    color: #999;
  }

  &:hover {
    border-color: #ccc;
    box-shadow: 3px 3px 5px #ccc;
  }

  &.active {
    border-color: var(--el-color-primary);

    p {
      color: var(--el-color-primary);
      font-weight: bold;
    }

    span {
      color: #666;
    }
  }
}

.flow-node-wrap {
  display: flex;
  white-space: nowrap;
}

.flow-node {
  display: flex;
  width: 18em;
  flex-shrink: 0;
  margin-right: 16px;
  margin-bottom: 15px;
  flex-direction: column;
  font-size: 0.9em;

  .node-name {
    display: flex;
    align-items: center;
    padding: 5px 10px;
    margin-right: -20px;
    // background-color: var(--el-bg-color-page);
    background: url("data:image/svg+xml;charset=utf-8,%3Csvg t='1755228742853' class='icon' viewBox='0 0 1702 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='15610' data-spm-anchor-id='a313x.search_index.0.i8.6e8f3a81r1hw4J' width='60' height='60'%3E%3Cpath d='M1701.385 541.177l-230.083-234.545H0l216.77 233.967L0 776.004h1471.302z' p-id='15611' data-spm-anchor-id='a313x.search_index.0.i7.6e8f3a81r1hw4J' class='' fill='%23d9e6ff'%3E%3C/path%3E%3C/svg%3E") no-repeat right 52% / 105% auto;
    margin-bottom: 7px;

    .node-index {
      font-size: 1.6em;
      font-weight: bold;
      color: #fff;
      text-shadow: 1px 1px 4px #999;
    }

    .node-remark {
      font-size: 0.75em;
      color: #aaa;
      white-space: nowrap;
      /* 防止文本换行 */
      overflow: hidden;
      /* 隐藏超出部分的文本 */
      text-overflow: ellipsis;
      /* 显示省略号 */
    }

    .node-tag {
      background: none;
    }
  }

  .node-tasks {
    flex: 1;
    padding: 12px 7px 5px;
    background-color: #f3f4fb;
    border-radius: 7px;

    .task-line {
      padding: 5px 10px;
      background-color: #fff;
      border-radius: 9px;
      margin-bottom: 9px;

      .task-title {
        display: flex;
        justify-content: space-between;
        align-items: center;

        .role-icon {
          display: flex;
          align-items: center;
          color: #999;
          font-size: 0.8em;
        }
      }

      .task-remark {
        font-size: 0.75em;
        margin-top: 5px;
        white-space: nowrap;
        /* 防止文本换行 */
        overflow: hidden;
        /* 隐藏超出部分的文本 */
        text-overflow: ellipsis;
        /* 显示省略号 */
      }

      .txt-ellipsis {
        white-space: nowrap;
        /* 防止文本换行 */
        overflow: hidden;
        /* 隐藏超出部分的文本 */
        text-overflow: ellipsis;
        /* 显示省略号 */
      }
    }
  }
}

/* 添加按钮 */
.flow-add-button {
  border: 1px dashed #d1d1d1;
  border-radius: 5px;
  padding: 15px;
  background-color: #fff;
  border-radius: 9px;
  margin-bottom: 9px;
  font-weight: bold;
  cursor: pointer;
  color: #9e9e9e;
  transition: all 0.3s ease-in-out;

  &:hover {
    border-color: var(--el-color-primary);
    color: var(--el-color-primary);
  }
}
</style>
